package com.example.plcopne.ui;

import android.app.PendingIntent;
import android.content.Intent;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.View;
import android.widget.EditText;



import com.example.plcopne.R;
import com.example.plcopne.utils.RxUtils;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import cc.lotuscard.ILotusCallBack;
import cc.lotuscard.LotusCardDriver;
import cc.lotuscard.LotusCardParam;
import io.reactivex.Observable;
import io.reactivex.functions.Consumer;

/**
 * NFC读取测试
 */
public class nfcActivity extends BaseActivity implements ILotusCallBack {

    private EditText m_edtLog;
    private UsbManager m_UsbManager = null;
    private UsbDevice m_LotusCardDevice = null;
    private UsbInterface m_LotusCardInterface = null;
    private UsbDeviceConnection m_LotusCardDeviceConnection = null;
    private final int m_nVID = 1306;
    private final int m_nPID = 20763;
    private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";

    private Boolean m_bCanUseUsbHostApi = true;
    private String m_strDeviceNode;


    private long m_nDeviceHandle = -1;
    private LotusCardDriver mLotusCardDriver;
    private UsbDeviceConnection m_UsbDeviceConnection;
    private UsbEndpoint m_OutEndpoint;
    private UsbEndpoint m_InEndpoint;




    private Boolean SetUsbCallBack() {
        Boolean bResult = false;
        PendingIntent pendingIntent;
        pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(
                ACTION_USB_PERMISSION), 0);
        m_UsbManager = (UsbManager) getSystemService(USB_SERVICE);
        if (null == m_UsbManager)
            return bResult;

        HashMap<String, UsbDevice> deviceList = m_UsbManager.getDeviceList();
        if (!deviceList.isEmpty()) {
            for (UsbDevice device : deviceList.values()) {
                if ((m_nVID == device.getVendorId())
                        && (m_nPID == device.getProductId())) {
                    m_LotusCardDevice = device;
                    m_strDeviceNode = m_LotusCardDevice.getDeviceName();
                    break;
                }
            }
        }
        if (null == m_LotusCardDevice)
            return bResult;
        m_LotusCardInterface = m_LotusCardDevice.getInterface(0);
        if (null == m_LotusCardInterface)
            return bResult;
        if (false == m_UsbManager.hasPermission(m_LotusCardDevice)) {
            m_UsbManager.requestPermission(m_LotusCardDevice, pendingIntent);
        }
        UsbDeviceConnection conn = null;
        if (m_UsbManager.hasPermission(m_LotusCardDevice)) {
            conn = m_UsbManager.openDevice(m_LotusCardDevice);
        }


        if (null == conn)
            return bResult;

        if (conn.claimInterface(m_LotusCardInterface, true)) {
            m_LotusCardDeviceConnection = conn;
        } else {
            conn.close();
        }
        if (null == m_LotusCardDeviceConnection)
            return bResult;
        // 把上面获取的对性设置到接口中用于回调操作
        m_UsbDeviceConnection = m_LotusCardDeviceConnection;
        if (m_LotusCardInterface.getEndpoint(1) != null) {
            m_OutEndpoint = m_LotusCardInterface.getEndpoint(1);
        }
        if (m_LotusCardInterface.getEndpoint(0) != null) {
            m_InEndpoint = m_LotusCardInterface.getEndpoint(0);
        }
        bResult = true;
        return bResult;
    }

    @Override
    public boolean callBackExtendIdDeviceProcess(Object objUser, byte[] arrBuffer) {
        return false;
    }

    @Override
    public boolean callBackReadWriteProcess(long nDeviceHandle, boolean bRead, byte[] arrBuffer) {
        int nResult = 0;
        boolean bResult = false;
        int nBufferLength = arrBuffer.length;
        int nWaitCount = 0;
        if (null == m_UsbDeviceConnection)
            return false;
        if (null == m_OutEndpoint)
            return false;
        if (null == m_InEndpoint)
            return false;
        if (nBufferLength < 65)
            return false;
        if (true == bRead) {
            arrBuffer[0] = 0;
            while (true) {
                nResult = m_UsbDeviceConnection.bulkTransfer(m_InEndpoint,
                        arrBuffer, 64, 3000);
                if (nResult <= 0)
                    break;
                if (arrBuffer[0] != 0) {
                    //此处调整一下
                    System.arraycopy(arrBuffer, 0, arrBuffer, 1, nResult);
                    arrBuffer[0] = (byte) nResult;
                    break;
                }
                nWaitCount++;
                if (nWaitCount > 1000)
                    break;
            }
            if (nResult == 64) {
                bResult = true;
            } else {
                bResult = false;

                Log.e("tag", "callBackReadWriteProcess1: ");


            }
        } else {
            nResult = m_UsbDeviceConnection.bulkTransfer(m_OutEndpoint,
                    arrBuffer, 64, 3000);
            if (nResult == 64) {
                bResult = true;
            } else {
                bResult = false;
                Log.e("tag", "callBackReadWriteProcess2: ");
            }
        }
        return bResult;
    }


    //M1 识别
    public void OnTestM1Listener(View view) {
        if (null == mLotusCardDriver)
            return;
        if (m_nDeviceHandle == -1) {
            m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0, 0, 0,// 使用内部默认超时设置
                    true);
        }
        if (m_nDeviceHandle != -1) {
            testIcCardReader(m_nDeviceHandle);
        } else {
        }


    }

    public void clear(View view) {
        m_edtLog.setText("");
        m_edtLog.setSelection(m_edtLog.getText().length());

    }


    //Cpu数据读取
    public void testCpuData(View view) {

        if (null == mLotusCardDriver)
            return;
        if (m_nDeviceHandle == -1) {
            m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0, 0, 0,// 使用内部默认超时设置
                    true);
        }

        if (m_nDeviceHandle != -1) {
            AddLog("Open Device Success!");
            testCpu(m_nDeviceHandle);
        } else {
            AddLog("Open Device False!");
        }


    }


    private void getIDCardData() {
        if (mLotusCardDriver == null) {
            return;
        }

        Observable.interval(1, 1, TimeUnit.SECONDS)
                .compose(RxUtils.schedulers())
                .as(RxUtils.bindLifecycle(this))
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        if (m_nDeviceHandle == -1) {
                            m_nDeviceHandle = mLotusCardDriver.OpenDevice("", 0, 0, 0, 0,// 使用内部默认超时设置
                                    true);
                        } else {
                            testIcCardReader(m_nDeviceHandle);
                        }
                    }
                });
    }


    private void testIcCardReader(long nDeviceHandle) {
        AddLog("------------------------------------------");
        boolean bResult = false;
        int nRequestType;
        long lCardNo = 0;
        LotusCardParam tLotusCardParam1 = new LotusCardParam();
        bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
        // bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
        if (!bResult) {
            AddLog("蜂鸣失败");
            return;
        }
        nRequestType = LotusCardDriver.RT_NOT_HALT;
        getCarStr(nDeviceHandle, nRequestType, tLotusCardParam1);

//        timeCancel();

    }

    private void getCradNo(long nDeviceHandle, int nRequestType, LotusCardParam tLotusCardParam1) {
        boolean bResult;
        long lCardNo;
        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("Call GetCardNo Error!");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);
        AddLog("Call GetCardNo Ok!");
        AddLog("CardNo(DEC):" + lCardNo);
        AddLog("CardNo(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[0]), 2)
                .toUpperCase());
        tLotusCardParam1.arrKeys[0] = (byte) 0xff;
        tLotusCardParam1.arrKeys[1] = (byte) 0xff;
        tLotusCardParam1.arrKeys[2] = (byte) 0xff;
        tLotusCardParam1.arrKeys[3] = (byte) 0xff;
        tLotusCardParam1.arrKeys[4] = (byte) 0xff;
        tLotusCardParam1.arrKeys[5] = (byte) 0xff;
        tLotusCardParam1.nKeysSize = 6;
        bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
                1, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call LoadKey Error!");
            return;
        }
        AddLog("Call LoadKey Ok!");
        bResult = mLotusCardDriver.Authentication(nDeviceHandle,
                LotusCardDriver.AM_A, 0, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Authentication(A) Error!");
            return;
        }
        AddLog("Call Authentication(A) Ok!");

        bResult = mLotusCardDriver.Read(nDeviceHandle, 1, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Read Error!");
            return;
        }
        AddLog("Call Read Ok!");


        AddLog("Buffer(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[4]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[5]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[6]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[7]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[8]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[9]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xa]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xb]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xc]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xd]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xe]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xf]), 2)
                .toUpperCase());
        tLotusCardParam1.arrBuffer[0] = (byte) 0x10;
        tLotusCardParam1.arrBuffer[1] = (byte) 0x01;
        tLotusCardParam1.arrBuffer[2] = (byte) 0x02;
        tLotusCardParam1.arrBuffer[3] = (byte) 0x03;
        tLotusCardParam1.arrBuffer[4] = (byte) 0x04;
        tLotusCardParam1.arrBuffer[5] = (byte) 0x05;
        tLotusCardParam1.arrBuffer[6] = (byte) 0x06;
        tLotusCardParam1.arrBuffer[7] = (byte) 0x07;
        tLotusCardParam1.arrBuffer[8] = (byte) 0x08;
        tLotusCardParam1.arrBuffer[9] = (byte) 0x09;
        tLotusCardParam1.arrBuffer[10] = (byte) 0x0a;
        tLotusCardParam1.arrBuffer[11] = (byte) 0x0b;
        tLotusCardParam1.arrBuffer[12] = (byte) 0x0c;
        tLotusCardParam1.arrBuffer[13] = (byte) 0x0d;
        tLotusCardParam1.arrBuffer[14] = (byte) 0x0e;
        tLotusCardParam1.arrBuffer[15] = (byte) 0x0f;
        tLotusCardParam1.nBufferSize = 16;
        bResult = mLotusCardDriver.Write(nDeviceHandle, 1, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Write Error!");
            return;
        }
        AddLog("Call Write Ok!");
    }

    private void getCarStr(long nDeviceHandle, int nRequestType, LotusCardParam tLotusCardParam1) {
        boolean bResult;
        long lCardNo;
        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("获取卡号失败");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);
        AddLog("卡号(DEC):" + lCardNo);
        tLotusCardParam1.arrKeys[0] = (byte) 0xff;
        tLotusCardParam1.arrKeys[1] = (byte) 0xff;
        tLotusCardParam1.arrKeys[2] = (byte) 0xff;
        tLotusCardParam1.arrKeys[3] = (byte) 0xff;
        tLotusCardParam1.arrKeys[4] = (byte) 0xff;
        tLotusCardParam1.arrKeys[5] = (byte) 0xff;
        tLotusCardParam1.nKeysSize = 6;
        bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
                1, tLotusCardParam1);
//        if (!bResult) {
//            AddLog("加载密钥失败");
//        } else {
//            AddLog("加载密钥成功");
//        }
        bResult = mLotusCardDriver.Authentication(nDeviceHandle,
                LotusCardDriver.AM_A, 1, tLotusCardParam1);
        Log.e("tag", "getCarStr: 密钥验证之前");
        if (!bResult) {
            AddLog("密钥验证失败");
        } else {
            Log.e("tag", "getCarStr: 密钥验证成功");
        }
        String readText = mLotusCardDriver.ReadText(nDeviceHandle, 1);
        String myString = readText.trim().replaceAll("\\s*|\t|\r|\n", "");
        Log.e("tag", "getCarStr: " + myString + "aaaa");


        if (myString.length() == 0) {
            AddLog("获取文本失败");
//            return;
        } else {
            AddLog("序列号为:" + myString);
        }

//        tLotusCardParam1.arrBuffer[0] = (byte) 0x10;
//        tLotusCardParam1.arrBuffer[1] = (byte) 0x01;
//        tLotusCardParam1.arrBuffer[2] = (byte) 0x02;
//        tLotusCardParam1.arrBuffer[3] = (byte) 0x03;
//        tLotusCardParam1.arrBuffer[4] = (byte) 0x04;
//        tLotusCardParam1.arrBuffer[5] = (byte) 0x05;
//        tLotusCardParam1.arrBuffer[6] = (byte) 0x06;
//        tLotusCardParam1.arrBuffer[7] = (byte) 0x07;
//        tLotusCardParam1.arrBuffer[8] = (byte) 0x08;
//        tLotusCardParam1.arrBuffer[9] = (byte) 0x09;
//        tLotusCardParam1.arrBuffer[10] = (byte) 0x0a;
//        tLotusCardParam1.arrBuffer[11] = (byte) 0x0b;
//        tLotusCardParam1.arrBuffer[12] = (byte) 0x0c;
//        tLotusCardParam1.arrBuffer[13] = (byte) 0x0d;
//        tLotusCardParam1.arrBuffer[14] = (byte) 0x0e;
//        tLotusCardParam1.arrBuffer[15] = (byte) 0x0f;
//        tLotusCardParam1.nBufferSize = 16;
//        bResult = mLotusCardDriver.Write(nDeviceHandle, 1, tLotusCardParam1);
//        if (!bResult) {
//            AddLog("Call Write Error!");
//            return;
//        }
//        AddLog("Call Write Ok!");
        AddLog("------------------------------------------");
    }

    //读取卡信息
    private void testIcCardReader2(long nDeviceHandle) {
        boolean bResult = false;
        int nRequestType;
        long lCardNo = 0;
        int nSectionIndex = 4;
        LotusCardParam tLotusCardParam1 = new LotusCardParam();
        bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
        if (!bResult) {
            AddLog("蜂鸣失败");
            return;
        }
        AddLog("蜂鸣成功");

        nRequestType = LotusCardDriver.RT_NOT_HALT;
        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("获取卡号失败");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);

        String s = byteToHex(tLotusCardParam1.arrCardNo);

        String s1 = Base64.encodeToString(tLotusCardParam1.arrCardNo, Base64.DEFAULT);
        AddLog("卡号(DEC):" + lCardNo);
        AddLog("卡号(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[0]), 2)
                .toUpperCase());
        tLotusCardParam1.arrKeys[0] = (byte) 0xff;
        tLotusCardParam1.arrKeys[1] = (byte) 0xff;
        tLotusCardParam1.arrKeys[2] = (byte) 0xff;
        tLotusCardParam1.arrKeys[3] = (byte) 0xff;
        tLotusCardParam1.arrKeys[4] = (byte) 0xff;
        tLotusCardParam1.arrKeys[5] = (byte) 0xff;
        tLotusCardParam1.nKeysSize = 6;
        bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
                nSectionIndex, tLotusCardParam1);
        if (!bResult) {
            AddLog("加载密钥失败");
            return;
        }
        AddLog("加载密钥成功");
        bResult = mLotusCardDriver.Authentication(nDeviceHandle,
                LotusCardDriver.AM_A, nSectionIndex, tLotusCardParam1);
        if (!bResult) {
            AddLog("验证密钥失败");

            return;
        }
        AddLog("验证密钥失败");
        bResult = mLotusCardDriver.Read(nDeviceHandle, nSectionIndex * 4, tLotusCardParam1);
        if (!bResult) {
            AddLog("读取失败");
            return;
        }
        AddLog("读取成功");
        //读取成功取消定时





/* //以下代码为有个客户专门要求的
        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("Call GetCardNo Error!");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);
        AddLog("Call GetCardNo Ok!");
        AddLog("CardNo(DEC):" + lCardNo);
        AddLog("CardNo(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[0]), 2)
                .toUpperCase());
        tLotusCardParam1.arrKeys[0] = (byte) 0xff;
        tLotusCardParam1.arrKeys[1] = (byte) 0xff;
        tLotusCardParam1.arrKeys[2] = (byte) 0xff;
        tLotusCardParam1.arrKeys[3] = (byte) 0xff;
        tLotusCardParam1.arrKeys[4] = (byte) 0xff;
        tLotusCardParam1.arrKeys[5] = (byte) 0xf1;
        tLotusCardParam1.nKeysSize = 6;
        bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
                2, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call LoadKey Error!");
            return;
        }
        AddLog("Call LoadKey Ok!");
        bResult = mLotusCardDriver.Authentication(nDeviceHandle,
                LotusCardDriver.AM_A, 2, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Authentication(A) Error!");
            //return;
        }
        else
        {
            bResult = mLotusCardDriver.Read(nDeviceHandle, 11, tLotusCardParam1);
        }

        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("Call GetCardNo Error!");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);
        AddLog("Call GetCardNo Ok!");
        AddLog("CardNo(DEC):" + lCardNo);
        AddLog("CardNo(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[0]), 2)
                .toUpperCase());
        tLotusCardParam1.arrKeys[0] = (byte) 0xff;
        tLotusCardParam1.arrKeys[1] = (byte) 0xff;
        tLotusCardParam1.arrKeys[2] = (byte) 0xff;
        tLotusCardParam1.arrKeys[3] = (byte) 0xff;
        tLotusCardParam1.arrKeys[4] = (byte) 0xff;
        tLotusCardParam1.arrKeys[5] = (byte) 0xff;
        tLotusCardParam1.nKeysSize = 6;
        bResult = mLotusCardDriver.LoadKey(nDeviceHandle, LotusCardDriver.AM_A,
                2, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call LoadKey Error!");
            return;
        }
        AddLog("Call LoadKey Ok!");
        bResult = mLotusCardDriver.Authentication(nDeviceHandle,
                LotusCardDriver.AM_A, 2, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Authentication Error!");
            return;
        }
        AddLog("Call LoadKey Ok!");
        AddLog("Call Authentication(A) Ok!");
        bResult = mLotusCardDriver.Read(nDeviceHandle, 8, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call Read Error!");
            return;
        }
        AddLog("Call Read Ok!");
        AddLog("Buffer(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[4]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[5]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[6]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[7]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[8]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[9]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xa]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xb]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xc]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xd]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xe]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrBuffer[0xf]), 2)
                .toUpperCase());
                */
    }


    private void testCpu(long nDeviceHandle) {
        byte arrSelectFile[] = {(byte) 0x00, (byte) 0xA4, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x08};
        byte arrReadFile[] = {(byte) 0x00, (byte) 0xB0, (byte) 0x00, (byte) 0x00, (byte) 0x00};
        boolean bResult = false;
        int nRequestType;
        long lCardNo = 0;
        int nSectionIndex = 4;
        LotusCardParam tLotusCardParam1 = new LotusCardParam();
        bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
        // bResult = mLotusCardDriver.Beep(nDeviceHandle, 10);
        if (!bResult) {
            AddLog("Call Beep Error!");
            return;
        }
        bResult = mLotusCardDriver.SetCardType(nDeviceHandle, 'A');
        if (!bResult) {
            AddLog("Call SetCardType Error!");
            return;
        }
        AddLog("Call SetCardType Ok!");
        nRequestType = LotusCardDriver.RT_NOT_HALT;
        bResult = mLotusCardDriver.GetCardNo(nDeviceHandle, nRequestType,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("Call GetCardNo Error!");
            return;
        }
        lCardNo = bytes2long(tLotusCardParam1.arrCardNo);
        AddLog("Call GetCardNo Ok!");
        AddLog("CardNo(DEC):" + lCardNo);
        AddLog("CardNo(HEX):"
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[3]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[2]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[1]), 2)
                .toUpperCase()
                + leftString(
                Integer.toHexString(tLotusCardParam1.arrCardNo[0]), 2)
                .toUpperCase());

        //获取ATS
        bResult = mLotusCardDriver.ResetCpuCardNoGetCardNo(nDeviceHandle,
                tLotusCardParam1);
        if (!bResult) {
            AddLog("Call ResetCpuCardNoGetCardNo Error!");
            return;
        }
        AddLog("ATS：" + toHexString(tLotusCardParam1.arrBuffer, 0, tLotusCardParam1.nBufferSize));
        tLotusCardParam1.arrCosSendBuffer[0] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[1] = (byte) 0x84;
        tLotusCardParam1.arrCosSendBuffer[2] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[3] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[4] = (byte) 0x08;
        tLotusCardParam1.unCosSendBufferLength = 5;
        bResult = mLotusCardDriver.SendCOSCommand(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call SendCOSCommand Error!");
            return;
        }
        AddLog("apdu result：" + toHexString(tLotusCardParam1.arrCosResultBuffer, 0, tLotusCardParam1.unCosReultBufferLength));
        //选择文件
        tLotusCardParam1.arrCosSendBuffer[0] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[1] = (byte) 0xA4;
        tLotusCardParam1.arrCosSendBuffer[2] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[3] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[4] = (byte) 0x02;
        tLotusCardParam1.arrCosSendBuffer[5] = (byte) 0x00;
        tLotusCardParam1.arrCosSendBuffer[6] = (byte) 0x08;
        tLotusCardParam1.unCosSendBufferLength = 7;
        bResult = mLotusCardDriver.SendCOSCommand(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call SendCOSCommand Error!");
            return;
        }
        AddLog("select file result：" + toHexString(tLotusCardParam1.arrCosResultBuffer, 0, tLotusCardParam1.unCosReultBufferLength));
/*        //写入文件
        System.arraycopy(arrWriteFile,0,tLotusCardParam1.arrCosSendBuffer,0,arrWriteFile.length);
        tLotusCardParam1.unCosSendBufferLength = arrWriteFile.length;
        bResult = mLotusCardDriver.SendCOSCommand(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call SendCOSCommand Error!");
            return;
        }
        AddLog("write file result："+toHexString(tLotusCardParam1.arrCosResultBuffer,0,tLotusCardParam1.unCosReultBufferLength));
*/
        System.arraycopy(arrSelectFile, 0, tLotusCardParam1.arrCosSendBuffer, 0, arrSelectFile.length);
        tLotusCardParam1.unCosSendBufferLength = arrSelectFile.length;
        bResult = mLotusCardDriver.SendCOSCommand(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call SendCOSCommand Error!");
            return;
        }
        AddLog("slelect file result：" + toHexString(tLotusCardParam1.arrCosResultBuffer, 0, tLotusCardParam1.unCosReultBufferLength));

        System.arraycopy(arrReadFile, 0, tLotusCardParam1.arrCosSendBuffer, 0, arrReadFile.length);
        tLotusCardParam1.unCosSendBufferLength = arrReadFile.length;
        bResult = mLotusCardDriver.SendCOSCommand(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call SendCOSCommand Error!");
            return;
        }
        AddLog("read file result：" + toHexString(tLotusCardParam1.arrCosResultBuffer, 0, tLotusCardParam1.unCosReultBufferLength));

        bResult = mLotusCardDriver.DeselectCpuCard(nDeviceHandle, tLotusCardParam1);
        if (!bResult) {
            AddLog("Call DeselectCpuCard Error!");
            return;
        }
        AddLog("DeselectCpuCard：" + toHexString(tLotusCardParam1.arrBuffer, 0, tLotusCardParam1.nBufferSize));

    }

    public long bytes2long(byte[] byteNum) {
        long num = 0;
        for (int ix = 3; ix >= 0; --ix) {
            num <<= 8;
            if (byteNum[ix] < 0) {
                num |= (256 + (byteNum[ix]) & 0xff);
            } else {
                num |= (byteNum[ix] & 0xff);
            }
        }
        return num;
    }

    private final static char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F'};

    public static String toHexString(byte[] d, int s, int n) {
        final char[] ret = new char[n * 2];
        final int e = s + n;

        int x = 0;
        for (int i = s; i < e; ++i) {
            final byte v = d[i];
            ret[x++] = HEX[0x0F & (v >> 4)];
            ret[x++] = HEX[0x0F & v];
        }
        return new String(ret);
    }

    public void AddLog(String strLog) {
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss:SSS");
        Date curDate = new Date(System.currentTimeMillis());// 获取当前时间
        String strDate = formatter.format(curDate);
        if (null == m_edtLog)
            return;
        String strLogs = m_edtLog.getText().toString().trim();
        if (strLogs.equals("")) {
            strLogs = strDate + " " + strLog;
        } else {
            strLogs += "\r\n" + strDate + " " + strLog;
        }

        Log.e("tag", strLogs);


        String finalStrLogs = strLogs;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                m_edtLog.setText(finalStrLogs);
                m_edtLog.setSelection(m_edtLog.getText().length());
            }
        });

    }


    public String leftString(String strText, int nLeftLength) {
        if (1 == strText.length())
            strText = "0" + strText;
        if (strText.length() <= nLeftLength)
            return strText;

        return strText.substring(strText.length() - nLeftLength,
                strText.length());
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    /**
     * byte数组转hex
     *
     * @param bytes
     * @return
     */
    public static String byteToHex(byte[] bytes) {
        String strHex = "";
        StringBuilder sb = new StringBuilder("");
        for (int n = 0; n < bytes.length; n++) {
            strHex = Integer.toHexString(bytes[n] & 0xFF);
            sb.append((strHex.length() == 1) ? "0" + strHex : strHex); // 每个字节由两个字符表示，位数不够，高位补0
        }
        return sb.toString().trim();
    }

    @Override
    public void init(@org.jetbrains.annotations.Nullable Bundle savedInstanceState) {

        settitle("NFC测试");

        m_edtLog = findViewById(R.id.edtLog);
        // 设置USB读写回调 串口可以不用此操作
        m_bCanUseUsbHostApi = SetUsbCallBack();
        if (m_bCanUseUsbHostApi) {
        } else {
        }
        mLotusCardDriver = new LotusCardDriver();
        mLotusCardDriver.m_lotusCallBack = this;

        getIDCardData();

    }

    @Override
    public int getContentView() {
        return R.layout.act_nfc;
    }
}
